package com.freak.wanandroid.model.discover.entity.faq;

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;
import java.util.List;

public class FaqEntity implements Serializable {

    /**
     * curPage : 1
     * datas : [{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>更终排查crash遇到一些奇奇怪怪的问题，总感觉在某些状态下，用户的运行时so、资源等发生了变化，但代码还是历史版本的。<\/p>\r\n<p>间接了解到了今天的这个问题：<\/p>\r\n<ol>\r\n<li>App在运行状态，可以动态安装apk，并且不重新启动吗？<\/li>\r\n<li>该逻辑一般可能在何种状态下触发？<\/li>\r\n<li>源码上分析流程是怎么样的？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":24452,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/24452","niceDate":"2022-09-28 14:17","niceShareDate":"2022-09-28 14:17","origin":"","prefix":"","projectLink":"","publishTime":1664345853000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1664345833000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | App在运行状态，可以动态安装apk，并且不重新启动吗？","type":1,"userId":2,"visible":1,"zan":0},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>周末学习无意看到的，题目源自接口时间的<a href=\"http://gk.link/a/11wFF\">深入 C 语言和程序运行原理<\/a>，一起来看问题吧。<\/p>\r\n<pre><code>\r\n#include &lt;stdio.h&gt;\r\nint main(void) {\r\n  int x = -10;\r\n  unsigned int y = 1;\r\n  if (x &lt; y) {\r\n    printf(&quot;x is smaller than y.&quot;);\r\n  } else {\r\n    printf(&quot;x is bigger than y.&quot;);  \r\n  }\r\n  return 0;\r\n}\r\n<\/code><\/pre><p>这样的一段代码，问题来了：<\/p>\r\n<ol>\r\n<li>更终会输出哪个分支？<\/li>\r\n<li>造成这样的原因是？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":23646,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/23646","niceDate":"2022-07-24 11:55","niceShareDate":"2022-07-24 11:54","origin":"","prefix":"","projectLink":"","publishTime":1658634914000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1658634889000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | C 语言中的隐式替换造成的奇怪的逻辑","type":1,"userId":2,"visible":1,"zan":6},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>当应用在运行过程中遇到异常状态，logcat中可能包含有用的辅助信息？<\/p>\r\n<p>例如在发生崩溃、ANR、严重丢帧时，如果能把近期的logcat信息一起上报上来辅助信息就好了。<\/p>\r\n<p>那么问题来了：<\/p>\r\n<ol>\r\n<li>如何获取当前应用产生的logcat信息呢？<\/li>\r\n<li>如何获取整个系统运行时产出的logcat信息呢？<\/li>\r\n<\/ol>\r\n<p>问题比较难，可以探索，不需要两问都回答哈。<\/p>","descMd":"","envelopePic":"","fresh":false,"host":"","id":23479,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/23479","niceDate":"2022-07-13 08:49","niceShareDate":"2022-07-13 08:49","origin":"","prefix":"","projectLink":"","publishTime":1657673399000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1657673382000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | 如何在崩溃时，如何获得logcat信息？","type":1,"userId":2,"visible":1,"zan":7},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>一般前后台切换，大家用的更多的就是利用 <\/p>\r\n<ol>\r\n<li>Application.ActivityLifecycleCallbacks 来做监听；<\/li>\r\n<li>利用ProcessLifecycle做监听；<\/li>\r\n<\/ol>\r\n<p>问题来了，这两种方式，对于涉及到多进程的地方，结果预期都不太正确，例如：<\/p>\r\n<p>App包含 ActivityA,ActivityB(另一个进程:otherprocess)<\/p>\r\n<p>当 ActivityA 跳转到 ActivityB时，如果利用上述两种方式，那么主进程已经回调处于后台了，但是其实ActivityB也是当前app的页面，所以应该还算处于前台才对。<\/p>\r\n<p>对于涉及到多进程的情况，如何完美解决呢？<\/p>\r\n<blockquote>\r\n<p><a href=\"https://www.wanandroid.com/wenda/show/8857?fid=9695&amp;date=2022_07_02_10_10_50&amp;message=Android%E4%B8%AD%E5%89%8D%E5%90%8E#msg_id2486\">问题来源<\/a><\/p>\r\n<\/blockquote>","descMd":"","envelopePic":"","fresh":false,"host":"","id":23347,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/23347","niceDate":"2022-07-03 10:53","niceShareDate":"2022-07-03 10:52","origin":"","prefix":"","projectLink":"","publishTime":1656816780000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1656816760000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"大家提问 Android中前后台切换监听，如果涉及到多进程如何完美的解决？","type":1,"userId":2,"visible":1,"zan":0},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>更近一直关注合规问题，其中有一次被检测到风险是：<\/p>\r\n<p>在Google的pixel设备中，某个进程被杀死后，然后又自动被「拉活」了，排查发现可能是各种注册的Service因为其onStartCommand返回START_STICKY导致。<\/p>\r\n<p>那么问题来了：<\/p>\r\n<ol>\r\n<li>当Service onStartCommand返回START_STICKY后，进程被杀系统是如何「复活」所在进程的？<\/li>\r\n<li>面对项目中一堆Service可能返回START_STICKY，如何可以在原生系统上避免被「拉活」？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":22539,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/22539","niceDate":"2022-07-24 11:50","niceShareDate":"2022-04-27 11:39","origin":"","prefix":"","projectLink":"","publishTime":1658634612000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1651030758000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | Service onStartCommand 返回STICKY是如何做到被拉活的？","type":0,"userId":2,"visible":0,"zan":6},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>Android中的匿名binder是何时调用IPCThreadState.joinThreadPool()方法的，<\/p>\r\n<p>或者是说，android中的匿名binder的server端是在何时挂起自己等待客户端唤醒的？<\/p>\r\n<p>例如bindservice时，传入的ServiceConnection这个匿名的Service。<\/p>\r\n<blockquote>\r\n<p>来自<a href=\"https://wanandroid.com/user/132308/articles/1\">initLiu<\/a>，<a href=\"https://wanandroid.com/wenda/show/8857?fid=132308&amp;date=2022_05_25_18_35_38&amp;message=Android%E4%B8%AD%E7%9A%84%E5%8C%BF#msg_id2459\">问题<\/a><\/p>\r\n<\/blockquote>","descMd":"","envelopePic":"","fresh":false,"host":"","id":22814,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/22814","niceDate":"2022-07-03 10:48","niceShareDate":"2022-05-25 21:00","origin":"","prefix":"","projectLink":"","publishTime":1656816489000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1653483610000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"【大家提问】Android中的匿名binder与线程相关的一些问题","type":0,"userId":2,"visible":0,"zan":0},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>很久前我们提问过:<\/p>\r\n<p><a href=\"https://www.wanandroid.com/wenda/show/8680\">每日一问 在Activity 的 onResume 方法中 view.postRunnable 能获取到 View 宽高吗？<\/a><\/p>\r\n<p>相信大家对于View.post都比较熟悉了，有个API与之非常类似：<\/p>\r\n<ol>\r\n<li>View.postOnAnimation 与View.post相比有什么区别？<\/li>\r\n<li>在什么情况下比较适合使用View.postOnAnimation呢？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":22845,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/22845","niceDate":"2022-07-03 10:47","niceShareDate":"2022-05-27 20:53","origin":"","prefix":"","projectLink":"","publishTime":1656816478000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1653656034000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 View.post 又来了与View.postOnAnimation 有什么区别？","type":0,"userId":2,"visible":0,"zan":4},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p><strong> 前提条件：<\/strong><br><strong>mView为VISIBLE状态<\/strong><br>执行：<\/p>\r\n<pre><code>  private fun startHideAnimation() {\r\n        mView.isVisible = false\r\n        mView.startAnimation(AlphaAnimation(1.0f else 0.0f).apply {\r\n            //如果将fillAfter设置为true,即使为gone,也能接收到事件,分析下为啥?\r\n            //            fillAfter = true\r\n            duration = 250\r\n        })\r\n    }\r\n<\/code><\/pre><p><strong>现象：<\/strong><br>view会先执行完动画完后才GONE<br><strong>问题：<\/strong><br>查看源码：<br><code>view.isVisible = GONE<\/code> 会经历下面的流程<\/p>\r\n<pre><code>public void setVisibility(@Visibility int visibility) {\r\n        setFlags(visibility, VISIBILITY_MASK);\r\n    }\r\n\r\n\r\nvoid setFlags(int flags, int mask) {\r\n            //忽略部分代码\r\n\r\n            if ((changed &amp; GONE) != 0) {\r\n                    requestLayout();\r\n\r\n                    if (mParent instanceof View) {\r\n                            // GONE views noop invalidation, so invalidate the parent\r\n                            ((View) mParent).invalidate(true);\r\n          }\r\n            }\r\n}\r\n<\/code><\/pre><p><code>startAnimation<\/code>会经历下面的流程：<\/p>\r\n<pre><code>public void setAnimation(Animation animation) {\r\n                //忽略部分代码\r\n        mCurrentAnimation = animation;\r\n                invalidate(true)\r\n}\r\n<\/code><\/pre><p>而动画执行的时机是在draw()中的<\/p>\r\n<pre><code>applyLegacyAnimation()\r\n<\/code><\/pre><p>但此时不是已经为GONE了吗，为啥仍然能够显示并执行完动画才消失呢。<br>其实把顺序调换了，现象也是一样。感觉跟view的绘制流程有关系，但无法分析透彻，请问why？<\/p>\r\n<blockquote>\r\n<p>本问题由<a href=\"https://wanandroid.com/wenda/show/8857?fid=105427&amp;date=2022_05_13_12_01_32&amp;message=%20%E5%89%8D%E6%8F%90%E6%9D%A1%E4%BB%B6%EF%BC%9AmVie\">张小飞的提问<\/a><\/p>\r\n<\/blockquote>","descMd":"","envelopePic":"","fresh":false,"host":"","id":22665,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/22665","niceDate":"2022-06-12 14:41","niceShareDate":"2022-05-13 21:53","origin":"","prefix":"","projectLink":"","publishTime":1655016109000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1652449986000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"【大家提问】为什么View.GONE效果不优先生效呢？","type":0,"userId":2,"visible":0,"zan":5},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>在我们日常开发过程中，可能会遇到一类比较难搞的crash：<code>java.lang.VerifyError<\/code>，问题来了：<\/p>\r\n<ol>\r\n<li>哪些情况可能会导致运行时发生VerifyError？<\/li>\r\n<li>如何前置发现相关问题，而不必等到运行到相关代码导致应用崩溃；<\/li>\r\n<li>【引申问题】对于verify还有一类为dex2oat阶段verify failed，需要运行时额外在做一次classverify，可能会导致一定的性能损耗，对此情况如何避免？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":22606,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/22606","niceDate":"2022-05-27 20:55","niceShareDate":"2022-05-06 11:35","origin":"","prefix":"","projectLink":"","publishTime":1653656113000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1651808113000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问| 如何前置发现VerifyError相关问题？","type":0,"userId":2,"visible":0,"zan":0},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>前两天看公众号文章：<br><a href=\"https://mp.weixin.qq.com/s/XHbJ1L5_rdvKs3AjLCvGiA\">分享一个困惑很久的问题：App前台，Activity会被回收吗？<\/a><\/p>\r\n<p>文章中源码分析阶段，看到了一些核心类：<\/p>\r\n<pre><code> ActivityRecord、TaskRecord、ActivityStack、ActivityDisplay、ActivityStackSupervisor\r\n<\/code><\/pre><p>绕起来有点晕。<\/p>\r\n<p>问题来了：<\/p>\r\n<ol>\r\n<li>这些类分别起到什么作用？<\/li>\r\n<li>有什么好的方式帮助记忆吗？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":21681,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/21681","niceDate":"2022-05-06 11:37","niceShareDate":"2022-03-07 21:24","origin":"","prefix":"","projectLink":"","publishTime":1651808232000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1646659440000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | ActivityRecord、TaskRecord、ActivityStack、ActivityDisplay、ActivityStackSupervisor 分别是干什么的？","type":0,"userId":2,"visible":1,"zan":13},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>有时候我们会通过adb shell查看安装的debug的包一些资源信息，例如查看：<\/p>\r\n<pre><code>/proc/pid/fd\r\n<\/code><\/pre><p>该目录下包含该进程运行是所有打开的fd相关信息。<\/p>\r\n<p>如果我们直接adb shell，然后 cd /proc/pid/fd，你会发现会<code>Permission denied<\/code>。<\/p>\r\n<p>这个时候我们可以选择执行：<\/p>\r\n<pre><code>run-as 包名\r\ncd /proc/pid/fd\r\n<\/code><\/pre><p>就可以了。<\/p>\r\n<p>问题来了：<strong>run-as背后做了什么？<\/strong><\/p>\r\n<blockquote>\r\n<p>以后至少每周更新一篇。<\/p>\r\n<\/blockquote>","descMd":"","envelopePic":"","fresh":false,"host":"","id":22438,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/22438","niceDate":"2022-05-06 11:37","niceShareDate":"2022-04-15 21:11","origin":"","prefix":"","projectLink":"","publishTime":1651808228000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1650028301000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问  | run-as 背后做了什么？","type":0,"userId":2,"visible":1,"zan":5},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>正在我们在开发的时候，涉及到需要跨进程通信，尤其是较为复杂的，需要拿到服务端 binder 代理进行交互的方式。<\/p>\r\n<p>一般流程为：<\/p>\r\n<ol>\r\n<li>编写 aidl 文件；<\/li>\r\n<li>实现一个 Service 子类(独立进程)，复写 onBind 方法，返回 Binder&#39;s Stub；<\/li>\r\n<li>主进程通过调用 bindService，间接拿到 binder 驱动，然后实现 binder 通信；<\/li>\r\n<\/ol>\r\n<p>更进一步的说，很多时候，我们也可以不依赖 aidl 文件，自己去实现Stub、Proxy类，利用 binder 驱动通过 transact 方法与服务端 Stub onTransact 进行跨进程交互。<\/p>\r\n<p>但是依然是需要依赖 bindService 方法，去获取 binder驱动。<\/p>\r\n<p>可以参考：<a href=\"https://blog.csdn.net/lmj623565791/article/details/38461079/\">Android aidl Binder框架浅析<\/a><\/p>\r\n<p>不过我们今天的关注点在于：<\/p>\r\n<ol>\r\n<li>可以不通过 bindService ，利用别的方式来传递 \u201cbinder 驱动\u201d来实现跨进程通信吗？<\/li>\r\n<li>framework 层有哪些地方使用了 1 的方式进行通信？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":21630,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/21630","niceDate":"2022-04-27 23:43","niceShareDate":"2022-03-02 00:40","origin":"","prefix":"","projectLink":"","publishTime":1651074190000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1646152857000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | 可以不借助 bindService，实现跨进程 binder 通信吗？","type":0,"userId":2,"visible":1,"zan":17},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>之前小缘在群里问过这个问题：<\/p>\r\n<p><img src=\"https://wanandroid.com/blogimgs/122c7a4f-12e7-4b59-833b-0a2a1631661d.png\" alt=\"截屏2022-02-10 下午5.27.05.png\" /><\/p>\r\n<blockquote>\r\n<p>先不考虑其实际的使用价值，单纯从技术角度思考，其实也有场景能用上，暂时不表。<\/p>\r\n<\/blockquote>\r\n<p>我细化一下问题：<\/p>\r\n<p>前提类：<\/p>\r\n<pre><code>public class A {\r\n\r\n    private final AInner inner = new AInner();\r\n\r\n    private final class AInner {\r\n\r\n        public void b() {\r\n            Log.d(&quot;tec-hack&quot;, &quot;AInner b invoke&quot;);\r\n        }\r\n    }\r\n}\r\n<\/code><\/pre><p>注意，暂且认为该类是系统类，我们无法在编译期对齐修改。<\/p>\r\n<p>问题来了：<\/p>\r\n<ol>\r\n<li>如何构造一个AInner的子类对象？<\/li>\r\n<li>完成对A的inner成员变量替换。<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":21409,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/21409","niceDate":"2022-04-15 21:13","niceShareDate":"2022-02-11 14:21","origin":"","prefix":"","projectLink":"","publishTime":1650028413000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1644560499000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | 被声明为private final 的内部类，能生成一个子类对象吗？逆天篡改~","type":0,"userId":2,"visible":0,"zan":12},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>之前有聊过：<a href=\"https://www.wanandroid.com/wenda/show/18615\">每日一问 | 我们经常说到的 Android 脱糖指的是什么？<\/a>  已经有同学提到可能会影响到编译期间 Transform 的编写。<\/p>\r\n<p>今天就来详细了解下，例如比较常见的需求：<\/p>\r\n<p><strong>在编译期间通过字节码处理View防止重复点击<\/strong><\/p>\r\n<ol>\r\n<li>在该案例下，需要了解脱糖的时机以及流程么？<\/li>\r\n<li>脱糖对该案例会造成什么样的影响？<\/li>\r\n<li>对于导致的问题，如何处理呢？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":20946,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/20946","niceDate":"2022-03-07 21:26","niceShareDate":"2021-12-25 18:39","origin":"","prefix":"","projectLink":"","publishTime":1646659580000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1640428781000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | 脱糖对于Android 打包期间插桩的有什么影响？","type":0,"userId":2,"visible":0,"zan":1},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>在我们学习 Java类加载流程的时候，一般都会提到：<\/p>\r\n<p>加载 -&gt; 连接 -&gt; 初始化 三个过程。<\/p>\r\n<p>问题来了：<\/p>\r\n<ol>\r\n<li>这三个过程中每个环节主要做哪些事？<\/li>\r\n<li>.class vs Class.forName() vs loadClass()  这三者有什么不同？可以结合三个过程来描述<\/li>\r\n<li>Android 中类加载有个 verify class的过程上述哪个流程会触发？什么情况下会出现 verify class error 情况？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":21251,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/21251","niceDate":"2022-02-11 14:22","niceShareDate":"2022-01-19 00:51","origin":"","prefix":"","projectLink":"","publishTime":1644560546000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1642524702000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 .class vs Class.forName() vs loadClass() 类加载傻傻分不清楚？","type":0,"userId":2,"visible":1,"zan":1},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>在上一问中：<\/p>\r\n<p><a href=\"https://wanandroid.com/wenda/show/20535\">每日一问 | android hidden api 不是禁用反射，以及如何突破，「元反射」不行了？<\/a><\/p>\r\n<p>中，我也从中学到了很多，其实我预期的答案是小缘所回来的。但是，其他同学的回答完全超出预期，尤其是这个库<a href=\"https://github.com/LSPosed/AndroidHiddenApiBypass\">https://github.com/LSPosed/AndroidHiddenApiBypass<\/a> 里面的 UnSafe 操作太秀了。<\/p>\r\n<p>刚哥也提到 stub api 的方式，也能某些情况下解决问题。<\/p>\r\n<p>忽然想到一个问题：<\/p>\r\n<p>如果一个接口是 hidden 的，我们是否可以构造出其实现类？如果可以，有几种方式呢？<\/p>\r\n<p>更后，我们团队一直在招人，欢迎联系<a href=\"https://wanandroid.com/blog/show/2949\">招聘要求<\/a><\/p>","descMd":"","envelopePic":"","fresh":false,"host":"","id":20867,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/20867","niceDate":"2022-02-08 23:51","niceShareDate":"2021-12-19 17:15","origin":"","prefix":"","projectLink":"","publishTime":1644335483000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1639905347000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问  | 如何构造一个 hide interface 的实现类？","type":0,"userId":2,"visible":1,"zan":2},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>出这个问题有两个原因：<\/p>\r\n<ol>\r\n<li>之前在公众号推文，很多同学认为android 9之后只要是反射都不被允许了，希望拨正这个观念；<\/li>\r\n<li>虽然已经有很多好文提到android hidden api如何突破，但是大多是都是基于android 9来测试的，实际上随着targetSDKVersion的提升，很多方案都失效了，包括「反射的反射」这个方案，所以我觉得还是可以讨论下；<\/li>\r\n<\/ol>\r\n<p>那么问题来了：<\/p>\r\n<ol>\r\n<li>hidden api是指不让使用反射吗？<\/li>\r\n<li>hidden api list在每个系统版本上，怎么知道哪些api被限制反射使用呢？<\/li>\r\n<li>hidden api 官方的限制思路是怎么样的？<\/li>\r\n<li>目前市面上突破android hidden api的方案，能够支持targetSDKVersion 提升到android 10 , 11, 12吗？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":20535,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/20535","niceDate":"2022-02-08 23:51","niceShareDate":"2021-11-19 11:57","origin":"","prefix":"","projectLink":"","publishTime":1644335474000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1637294221000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | android hidden api 不是禁用反射，以及如何突破，「元反射」不行了？","type":0,"userId":2,"visible":1,"zan":22},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>Gson大家一定不陌生，在很多项目中都大规模使用。<\/p>\r\n<p>例如常见的：<\/p>\r\n<pre><code>网络请求\r\n    -&gt;返回Json数据\r\n    -&gt;Gson解析为对象\r\n    -&gt;渲染页面\r\n<\/code><\/pre><p>很多时候，历史项目包含很多Gson解析对象在UI线程的操作，或者说即使在子线程其实也会影响页面展现速度。<\/p>\r\n<p>大家都了解Gson对于对象的解析，如果不单独的配置TypeAdapter，那么其实内部是充满反射的。<\/p>\r\n<p>问题来了：<\/p>\r\n<p><strong>有没有什么低侵入的方案可以尽可能去除反射操作，从而提升运行效率？描述思路即可。<\/strong><\/p>","descMd":"","envelopePic":"","fresh":false,"host":"","id":19623,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/19623","niceDate":"2021-12-02 00:50","niceShareDate":"2021-08-30 21:36","origin":"","prefix":"","projectLink":"","publishTime":1638377423000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1630330596000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | Gson中序列化对象的操作有低侵入的优化方案吗？","type":0,"userId":2,"visible":1,"zan":10},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>今天意外在崩溃上报平台发现一个异常为UndeclaredThrowableException，看名字就比较好奇，大家可以搜索下，尝试回答：<\/p>\r\n<ol>\r\n<li>什么时候会抛出此异常？<\/li>\r\n<li>为什么[1]中重新封装为此异常抛出，这么设计的原因是？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":20514,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/20514","niceDate":"2021-12-02 00:50","niceShareDate":"2021-11-17 00:56","origin":"","prefix":"","projectLink":"","publishTime":1638377410000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1637081819000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 UndeclaredThrowableException 是什么异常？","type":0,"userId":2,"visible":1,"zan":2},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>问题如题：<\/p>\r\n<p>ViewGroup 的 measureChild 方法和 measureChildWithMargins 方法的区别是什么，如何在实际开发中决定选择使用哪一个？<\/p>\r\n<p>来源：<a href=\"https://wanandroid.com/wenda/show/8857?fid=833&amp;date=2021_10_12_09_13_15&amp;message=ViewGroup#msg_id2204\">可以从这里提问<\/a>，欢迎大家踊跃提问~<\/p>","descMd":"","envelopePic":"","fresh":false,"host":"","id":20130,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/20130","niceDate":"2021-12-02 00:50","niceShareDate":"2021-10-12 20:20","origin":"","prefix":"","projectLink":"","publishTime":1638377400000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1634041255000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"【大家提问】 | ViewGroup 的 measureChild 方法和 measureChildWithMargins 方法的区别是什么？","type":0,"userId":2,"visible":1,"zan":9},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>关于 Activity 重建，我们探究几个问题：<\/p>\r\n<ol>\r\n<li>当前 app 正在前台运行，不在栈顶的 Activity 有可能会因为系统资源，例如内存等不足回收吗？<\/li>\r\n<li>当 app 处于后台运行，app 进程未被杀死，其内部的 Activity 会被回收吗？<\/li>\r\n<li>当 app 处于后台运行，app 的进程会被杀死吗？<\/li>\r\n<\/ol>\r\n<p>如果有能力，建议解释过程中可以配合源码，不一定要全部答出来~<\/p>","descMd":"","envelopePic":"","fresh":false,"host":"","id":18965,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/18965","niceDate":"2021-08-30 21:37","niceShareDate":"2021-07-15 00:27","origin":"","prefix":"","projectLink":"","publishTime":1630330636000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1626280047000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | 关于 Activity 重建，值得探究的几个问题","type":0,"userId":2,"visible":1,"zan":19},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>了解应用启动相关代码的同学一定知道：<\/p>\r\n<p>我们的应用启动时，每个进程会对应一个ActivityThread对象，而Application对象在正常情况下也是每个进程只有一个？<\/p>\r\n<p>但是如果你看ActivityThread的源码，你会发现：<\/p>\r\n<pre><code>public final class ActivityThread {\r\n    final ArrayList&lt;Application&gt; mAllApplications\r\n                = new ArrayList&lt;Application&gt;();\r\n    ...\r\n}\r\n<\/code><\/pre><p><a href=\"https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/ActivityThread.java;l=237?q=ActivitYtHREAD&amp;sq=&amp;ss=android%2Fplatform%2Fsuperproject\">源码直达<\/a><\/p>\r\n<p>问题来了：<\/p>\r\n<ol>\r\n<li>什么情况下一个ActivityThread对象，会对应多个Application对象，即mAllApplications.size() &gt; 1；<\/li>\r\n<li>如果找到了1的情况，支持这个目的是？<\/li>\r\n<\/ol>\r\n<blockquote>\r\n<p>本问题归因为好奇，硬说使用场景在一些插件化中会尝试构造Application会调用这个，但是这个肯定不是google的本意。<\/p>\r\n<\/blockquote>","descMd":"","envelopePic":"","fresh":false,"host":"","id":19550,"isAdminAdd":false,"link":"https://wanandroid.com/wenda/show/19550","niceDate":"2021-08-30 21:36","niceShareDate":"2021-08-25 18:10","origin":"","prefix":"","projectLink":"","publishTime":1630330617000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1629886237000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | 好奇ActivityThread中为什么会有一个 Application的集合？","type":0,"userId":2,"visible":1,"zan":6},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>今天我们来讨论下 Jetpack 中的 ViewModel:<\/p>\r\n<p>大家都知道 ViewModel 有一个特点就是能够在 Activity 发生重建时做数据的恢复。<\/p>\r\n<p>我们就针对这个「重建」与「恢复」问一些问题：<\/p>\r\n<ol>\r\n<li>ViewModel 在 Activity 发生旋转等配置发生变化所导致的重建，能恢复数据吗？<\/li>\r\n<li>如果 1 能，尝试从源码角度分析，数据存在哪？怎么存储的？怎么读取的？<\/li>\r\n<li>当 Activity 切换到后台，被系统杀死（进程存活），此时回到 Activity 导致的重建，ViewModel 的数据能恢复吗？为什么？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":18930,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/18930","niceDate":"2021-08-25 18:11","niceShareDate":"2021-07-11 22:05","origin":"","prefix":"","projectLink":"","publishTime":1629886294000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1626012349000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | ViewModel 在什么情况下的「销毁重建」能够对数据进行无缝恢复？","type":0,"userId":2,"visible":1,"zan":30},{"adminAdd":false,"apkLink":"","audit":1,"author":"xiaoyang","canEdit":false,"chapterId":440,"chapterName":"官方","collect":false,"courseId":13,"desc":"<p>在我们的印象里，如果构造一个 Dialog 传入一个非 Activiy 的 context，则可能会出现 bad token exception。<\/p>\r\n<p>今天我们就来彻底搞清楚这一块，问题来了：<\/p>\r\n<ol>\r\n<li>为什么传入一个非 Activity 的 context 会出现错误？<\/li>\r\n<li>传入的 context 一定要是 Activity 吗？<\/li>\r\n<\/ol>","descMd":"","envelopePic":"","fresh":false,"host":"","id":18281,"isAdminAdd":false,"link":"https://www.wanandroid.com/wenda/show/18281","niceDate":"2021-07-11 22:06","niceShareDate":"2021-05-13 00:20","origin":"","prefix":"","projectLink":"","publishTime":1626012414000,"realSuperChapterId":439,"selfVisible":0,"shareDate":1620836414000,"shareUser":"","superChapterId":440,"superChapterName":"问答","tags":[{"name":"本站发布","url":"/article/list/0?cid=440"},{"name":"问答","url":"/wenda"}],"title":"每日一问 | Dialog 的构造方法的 context 必须传入 Activity吗？","type":0,"userId":2,"visible":1,"zan":24}]
     * offset : 0
     * over : false
     * pageCount : 7
     * size : 24
     * total : 163
     */

    @SerializedName("curPage")
    private int mCurPage;
    @SerializedName("offset")
    private int mOffset;
    @SerializedName("over")
    private boolean mOver;
    @SerializedName("pageCount")
    private int mPageCount;
    @SerializedName("size")
    private int mSize;
    @SerializedName("total")
    private int mTotal;
    @SerializedName("datas")
    private List<DatasEntity> mDatas;

    public int getCurPage() {
        return mCurPage;
    }

    public void setCurPage(int curPage) {
        mCurPage = curPage;
    }

    public int getOffset() {
        return mOffset;
    }

    public void setOffset(int offset) {
        mOffset = offset;
    }

    public boolean isOver() {
        return mOver;
    }

    public void setOver(boolean over) {
        mOver = over;
    }

    public int getPageCount() {
        return mPageCount;
    }

    public void setPageCount(int pageCount) {
        mPageCount = pageCount;
    }

    public int getSize() {
        return mSize;
    }

    public void setSize(int size) {
        mSize = size;
    }

    public int getTotal() {
        return mTotal;
    }

    public void setTotal(int total) {
        mTotal = total;
    }

    public List<DatasEntity> getDatas() {
        return mDatas;
    }

    public void setDatas(List<DatasEntity> datas) {
        mDatas = datas;
    }
}
